const WebSocket = require('ws');
const { FileBox } = require('file-box')
const path = require('path');
const fs = require('fs').promises;
const { Worker, isMainThread, parentPort } = require('worker_threads');
const XLSX = require('xlsx');
const { execSync } = require('child_process');
const mysql = require('mysql2/promise');
const { type } = require('os');

// 创建 WebSocket 服务器
const wss = new WebSocket.Server({ port: 12345 });

// 
/**
 * 记录机器人的状态信息
 * 0 --> 待扫码; 
 * 100 --> 已登录; 
 * 201 --> 已启动 
 * 已退出
 * 501 --> 异常
 */
var botStatus = {
    code: 0,
    message: '',
}

if (isMainThread) {
    // 主进程
    console.log(`主进程 ${process.pid} 正在运行`);

    const pool = mysql.createPool({
        host: 'xiaomtq.top',
        user: 'Supervision',
        password: '3B4GJyfdbBwc5EWy',
        database: 'SupervisionSystem'
    });

    // 创建工作线程
    const worker = new Worker(path.resolve(__dirname, 'botWorker.js'));

    // 监听工作线程的消息
    worker.on('message', mes => {
        console.log(`收到工作线程消息: ${JSON.stringify(mes)}`);
        // if (message.type === 'status') {
        //     botStatus = message.message;
        //     console.log(`机器人状态更新: ${botStatus}`);
        // } else if (message.type === 'error') {
        //     console.error(`工作线程错误: ${message.message}`);
        // }

        /**
         * 基于工作线程 发送过来的消息类型进行不同的操作
         */
        switch (mes.type) {
            case "status" || "error":
                // status 状态表示 机器人处于 待扫码 已登录 已启动 已退出 4中状态
                // ws.send(JSON.stringify({ type: "BotStatus", message: mes.message }))
                botStatus.code = mes.code;
                botStatus.message = mes.message
                break;

            case "error":
            // ws.send(JSON.stringify({ type: "BotStatus", message: "Bot is error" }))
            default:
                break;
        }
    });

    // 监听工作线程的错误
    worker.on('error', error => {
        console.error(`工作线程错误: ${error}`);
    });

    // 监听工作线程的退出
    worker.on('exit', code => {
        console.log(`工作线程退出，退出码: ${code}`);
        botStatus = 'Offline';
    });

    // websocket 服务器事件
    wss.on('connection', function connection(ws) {
        // 链接事件
        console.log('New client connected!');

        ws.on('message', async function incoming(message) {

            // 监听消息事件
            try {
                const data = JSON.parse(message);
                switch (data.type) {
                    // 更新课程方法
                    case 'UpdateCourseInfo':
                        // 将 Base64 字符串解码为 Buffer
                        const buffer = Buffer.from(data.data, 'base64');

                        // 创建 FileBox 对象
                        const fileBox = FileBox.fromBuffer(buffer);

                        // 确保目标目录存在
                        await fs.mkdir(path.join(__dirname, 'course'), { recursive: true });

                        // 将文件保存到本地
                        await fileBox.toFile(path.join(__dirname, 'course', data.fileName));

                        // 发送消息给客户端我已保存完毕
                        ws.send(JSON.stringify({ type: 'success', message: `正在加载课程文件：{ ${data.fileName} } ` }));

                        // 开始处理xlsx文件
                        const courseXls = XLSX.readFile(path.join(__dirname, 'course', data.fileName));

                        // 获取第一个工作表
                        const sheetName = courseXls.SheetNames[0];
                        const courseSheet = courseXls.Sheets[sheetName];

                        // 转换成JSON格式 从第二行开始读取
                        const xlsxData = XLSX.utils.sheet_to_json(courseSheet, { range: 2 });

                        // 获取表头
                        const headers = xlsxData[0];

                        // 筛选表头
                        const requireHeaders = ['上课院系', '上课班级', '排课人数', '选课人数', '开课单位', '开课课程', '授课教师', '开课时间', '上课地点', '上课周次', '星期']
                        // const headerIndices = requireHeaders.map(header => headers.indexOf(header))
                        const headerValues = Object.keys(headers)
                        // 查找所需表头的索引
                        const headerIndices = requireHeaders.map(header => headerValues.indexOf(header));

                        // 筛选数据
                        const filteredData = xlsxData.map(row => {
                            return headerIndices.reduce((obj, index, i) => {
                                obj[requireHeaders[i]] = row[requireHeaders[i]];
                                return obj;
                            }, {})
                        })

                        const result = {
                            headers: requireHeaders,
                            data: filteredData
                        }

                        console.log("课程数据", filteredData);
                        
                        ws.send(JSON.stringify({ type: 'filteredCourseData', message: result }));

                        for (let index = 0; index < filteredData.length; index++) {
                            const courseData = filteredData[index];
                            (async () => {
                                try {

                                    // 构建插入语句
                                    const columns = Object.keys(courseData).join(', ');
                                    const values = Object.values(courseData);
                                    const placeholders = values.map(() => '?').join(', ');

                                    const query = `INSERT INTO course (${columns}) VALUES (${placeholders})`;

                                    // 执行插入语句
                                    const [result] = await pool.query(query, values);

                                    // 检查插入结果
                                    if (result.affectedRows > 0) {
                                        ws.send(JSON.stringify({ type: 'success', message: 'DataBase Course inserted successfully.' }));
                                    } else {
                                        ws.send(JSON.stringify({ type: 'error', message: 'Failed to insert course.' }));
                                    }
                                } catch (err) {
                                    ws.send(JSON.stringify({ type: 'error', message: 'Database query error.' }));
                                    console.error('Error executing query:', err);
                                }
                            })();
                        }


                        break;
                    
                    // 获取课程数据
                    case 'GetCourseData':
                        (async () => {
                            try {
                                // 查询数据库表中的所有数据
                                const [rows] = await pool.query('SELECT * FROM course');
                        
                                // 将查询结果转换为对象数组
                                const courses = rows.map(row => ({
                                    college: row.college,
                                    class_name: row.class_name,
                                    scheduled_students: row.scheduled_students,
                                    selected_students: row.selected_students,
                                    department: row.department,
                                    course_name: row.course_name,
                                    teacher: row.teacher,
                                    class_time: row.class_time,
                                    location: row.location,
                                    weeks: row.weeks,
                                    weekday: row.weekday
                                }));
                        
                                // 发送结果
                                ws.send(JSON.stringify({ type: 'success', data: courses }));
                            } catch (err) {
                                ws.send(JSON.stringify({ type: 'error', message: '获取课程数据失败...' }));
                                console.error('Error executing query:', err);
                            }
                        })();
                    
                    // 登录方法
                    case 'Login':
                        const { userName, password } = data.data;

                        (async () => {
                            try {
                                const [rows] = await pool.query('SELECT * FROM user WHERE userName = ? AND password = ?', [userName, password]);

                                if (rows.length > 0) {
                                    ws.send(JSON.stringify({ type: 'success', message: 'Login successful.' }));
                                } else {
                                    ws.send(JSON.stringify({ type: 'error', message: 'Invalid username or password.' }));
                                }
                            } catch (err) {
                                ws.send(JSON.stringify({ type: 'error', message: 'Database query error.' }));
                                console.error('Error executing query:', err);
                                return
                            }
                        })();
                        break;
                    // 获取机器人状态
                    case 'GetBotStatus':
                        ws.send(JSON.stringify({ type: 'status', message: botStatus }));
                        break;
                    default:
                        break;
                }
            } catch (error) {
                console.error(error);
                console.log(error.message);
                ws.send(JSON.stringify({ type: 'error', message: error.message }));
            }
        });

        ws.on('close', function close() {
            console.log('Client disconnected!');
        });
    });
} else {
    // 工作线程
    // 这部分代码不会在主进程中执行
}